Pintools/angr 在 Linux/Windows 下的安装与使用

由于跑Re有时候遇见一些特别恶心的题,自己逆太麻烦,就可以跑pintools,但是Windows下的命令行真的好多坑,而且尝试在windows上面安装的时候发现Windows由于库太繁琐,花费的时间更久,于是放弃windows上跑pintools的计划,在linux下面跑,一番折磨终于安装上了Pintools,傻xCSDN一堆没用的教程,把坑和过程记录于下

Linux

下载源码并解压

直接下载pintools的源码,地址

linux下面使用wget 即可,然后tar -zxvf pin-xxxxxx.tar.gz

编译instruction数量的插件

可能需要搞个make,大多数的系统都带有make,如果没有的话就sudo apt-get install make

目前用的比较多的就是inscount0/1/2 插件,就是我们传说中的看某个输入对应要消耗多少指令

1
2
cd source/tools/ManualExamples
make obj-intel64/inscount0.so TARGET=intel64

要编译成32位的可以用

1
make obj-ia32/inscount0.so

其中默认这个inscout0.cpp是输出到一个文件里面的,不太方便我们进行其他操作,我们需要在inscout0.cpp里面改一下再编译

1
2
3
4
5
6
7
8
41 VOID Fini(INT32 code, VOID *v)
42 {
43 // Write to a file since cout and cerr maybe closed by the application
44 // OutFile.setf(ios::showbase);
45 // OutFile << "Count " << icount << endl;
46 // OutFile.close();
47 std::cout << "Count:" << icount << std::endl;
48 }

Fini函数上面的给注释掉,填写这个cout,内容自定,然后再编译,编译出来了之后这个inscount0.so 的使用方法就是

1
pin -t <yourpintool> -- <executable>

然后就可以在stdin里面看到使用的指令,比如我用

1
pin -t myinscout.so -- /bin/sh -c exit

就可以看到输出

1
Count:1089205

于是就可以写python脚本了,以祥云杯的re1为例,由于结果是逐位比较的,所以就直接爆破就是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from subprocess import Popen, PIPE
from sys import argv
import string

pinPath = '/home/damaoooo/Downloads/pin-3.16-98275-ge0db48c31-gcc-linux/pin'
toolPath = '/home/damaoooo/Downloads/pin-3.16-98275-ge0db48c31-gcc-linux/source/tools/ManualExamples/obj-intel64/myinscount0.so'
elfPath = '/home/damaoooo/test/main'
pinRead = lambda : p.communicate()[0]
pinWrite = lambda cont : p.stdin.write(cont.encode())

table = '0123456789abcdef'
flag = ''
if __name__ == '__main__':
last = 0
found = 0
last_letter = ''
for idx in range(38 - 6):
for i in table:
if i == last_letter:
continue
found = 0
p = Popen([pinPath, '-t', toolPath, '--', elfPath], stdin=PIPE, stdout=PIPE)
s = 'flag{%s}'%(flag + i*(38 - 6 - len(flag)))+'\n'
pinWrite(s)
now = int(pinRead().split('Count:'.encode())[1])
delta = now - last
print('input{} -> ins{} -> delta({})'.format(s[:-1], now, now - last))
last = now
last_letter = i
if delta > 0 and delta < 10:
flag += i
found = 1
last_letter = ''
break
if found == 0:
flag = flag[:-1]


print(flag)

这里采用subprocess来开启一个进程,然后读取stdinstdout的输入输出进行交互进行爆破

Windows

windows下想用pintools真的非常困难了

首先还是下载源码包,修改源码,最难的是编译,因为windows下面的make,真的很难用

首先是要安装visual studio, 然后就是安装cygwin的make,最后添加环境之后,make还是不成功。

硬了,拳头硬了,而且看其他的博客说windows上面,即便是输入相同,输出的指令也不同,不得不说在这方面linux还是要好得多

弃坑不搞了

不如用angr来代替

angr

安装pip install angr

现在angr已经支持python3 了,不要再去找老教程里面还在python2 的啦

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import angr

# 新建工程,这个auto_load_libs加不加我这边影响确实不大
proj = angr.Project('<execute>', auto_load_libs=False)

# 创建模拟状态
state = proj.factory.entry_state()

# 创建模拟器
simgr = proj.factory.simgr(state)

# 开始探索
simgr.explore(find=0x54444444, avoid=0x400000)

# 输出结果
print (simgr.found[0].posix.dumps(0))